﻿using ShenNius.Repository;
using ShenNius.Repository.Extensions;
using ShenNius.Sys.API.Domain.Entity;
using ShenNius.Sys.API.Domain.Entity.Common;
using ShenNius.Sys.API.Domain.Repository;
using ShenNius.Sys.API.Dtos.Common;
using ShenNius.Sys.API.Infrastructure.Common;
using ShenNius.Sys.API.Infrastructure.Configs;
using SqlSugar;
using System;
using System.Threading.Tasks;

/*************************************
* 类名：RecycleService
* 作者：realyrare
* 邮箱：mahonggang8888@126.com
* 时间：2021/4/8 18:56:27
*┌───────────────────────────────────┐　    
*│　   版权所有：神牛软件　　　　	     │
*└───────────────────────────────────┘
**************************************/

namespace ShenNius.Sys.API.Infrastructure
{

    public class RecycleRepository : BaseRepository<Recycle>, IRecycleRepository
    {
        private readonly ICurrentUserContext _currentUserContext;

        public RecycleRepository(ISqlSugarClient db, ICurrentUserContext currentUserContext) : base(db)
        {
            _currentUserContext = currentUserContext;
        }
        public async Task<ApiResult> RestoreAsync(DeletesInput input)
        {
            try
            {
                db.Ado.BeginTran();
                //先删除后还原  要启用事务
                foreach (var item in input.Ids)
                {
                    var model = await GetModelAsync(d => d.Id == item);
                    if (model != null)
                    {
                        if (string.IsNullOrEmpty(model.RestoreSql))
                        {
                            throw new ArgumentNullException($"根据传递的【{item}】参数查出来该条数据不存在！");
                        }
                        var i = await db.Ado.ExecuteCommandAsync(model.RestoreSql);
                        if (i > 0)
                        {
                            //把回收站的记录清空
                            await DeleteAsync(d => d.Id == item);
                        }
                    }
                }
                db.Ado.CommitTran();
            }
            catch (Exception e)
            {
                db.Ado.RollbackTran();
                return new ApiResult(e.Message, 500);
            }
            return new ApiResult();
        }

        public async Task<ApiResult> RealyDeleteAsync(DeletesInput input)
        {
            var list = await GetListAsync(d => input.Ids.Contains(d.Id));
            if (list == null || list.Count <= 0)
            {
                throw new ArgumentNullException($"{nameof(input.Ids)}:中参数没有匹配到任何数据记录");
            }
            try
            {
                foreach (var item in list)
                {
                    if (item != null)
                    {
                        if (string.IsNullOrEmpty(item.RealyDelSql))
                        {
                            throw new ArgumentNullException($"根据传递的【{item}】参数查出来该条数据不存在！");
                        }
                        var i = await db.Ado.ExecuteCommandAsync(item.RealyDelSql);
                        if (i > 0)
                        {
                            //把回收站的记录清空
                            await DeleteAsync(d => d.Id == item.Id);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                return new ApiResult(e.Message, 500);
            }
            return new ApiResult();
        }

        public async Task<ApiResult> SoftDeleteAsync<TEntity>(DeletesTenantInput input, IBaseRepository<TEntity> service) where TEntity : BaseTenantEntity, new()
        {
            var userId = _currentUserContext.Id;
            var allTable = WebHelper.allDbTable;
            var currentName = _currentUserContext.Name;
            try
            {
                db.Ado.BeginTran();
                foreach (var item in input.Ids)
                {
                    var res = await service.UpdateAsync(d => new TEntity() { DeleteTime=DateTime.Now, IsDeleted=true }, d => d.Id == item && d.TenantId == input.TenantId && d.IsDeleted == false);
                    if (res <= 0)
                    {
                        var model = await service.GetModelAsync(d => d.Id == item);
                        if (model?.Id <= 0)
                        {
                            throw new ArgumentNullException($"根据传递的【{item}】参数查出来该条数据不存在！");
                        }
                        if (model.IsDeleted == false)
                        {
                            return new ApiResult("该条数据已经被删除了", 200);
                        }
                        throw new ArgumentNullException("删除失败了！");
                    }
                    var tableName = new TEntity().GetType().Name;
                    if (!string.IsNullOrEmpty(allTable))
                    {
                        var allTableArry = allTable.Split(',');
                        for (int j = 0; j < allTableArry.Length; j++)
                        {
                            if (allTableArry[j].Contains(tableName))
                            {
                                tableName = allTableArry[j];
                                break;
                            }
                        }
                    }
                    var recycle = Recycle.Create(item, userId, tableName, input.TenantId, currentName);
                    var i = await AddAsync(recycle);
                    if (i <= 0)
                    {
                        throw new ArgumentNullException("删除成功了，但是放进回收站时失败了！");
                    }
                }
                db.Ado.CommitTran();
            }
            catch (Exception e)
            {
                db.Ado.RollbackTran();
                return new ApiResult(e.Message, 500);
            }
            return new ApiResult();
        }


        public async Task<ApiResult> SoftDeleteAsync<TEntity>(DeletesInput input, IBaseRepository<TEntity> service) where TEntity : BaseEntity, new()
        {
            var userId = _currentUserContext.Id;
            var allTable = WebHelper.allDbTable;
            var currentName = _currentUserContext.Name;
            try
            {
                db.Ado.BeginTran();
                foreach (var item in input.Ids)
                {
                    var res = await service.UpdateAsync(d => new TEntity() { DeleteTime = DateTime.Now, IsDeleted = true }, d => d.Id == item && d.IsDeleted == false);
                    if (res <= 0)
                    {
                        var model = await service.GetModelAsync(d => d.Id == item);
                        if (model?.Id <= 0)
                        {
                            throw new ArgumentNullException($"根据传递的【{item}】参数查出来该条数据不存在！");
                        }
                        if (model.IsDeleted == false)
                        {
                            return new ApiResult("该条数据已经被删除了", 200);
                        }
                        throw new ArgumentNullException("删除失败了！");
                    }
                    var tableName = new TEntity().GetType().Name;
                    if (!string.IsNullOrEmpty(allTable))
                    {
                        var allTableArry = allTable.Split(',');
                        for (int j = 0; j < allTableArry.Length; j++)
                        {
                            if (allTableArry[j].Contains(tableName))
                            {
                                tableName = allTableArry[j];
                                break;
                            }
                        }
                    }
                    var recycle = Recycle.Create(item, userId, tableName, _currentUserContext.TenantId, currentName,false);
                    var i = await AddAsync(recycle);
                    if (i <= 0)
                    {
                        throw new ArgumentNullException("删除成功了，但是放进回收站时失败了！");
                    }
                }
                db.Ado.CommitTran();
            }
            catch (Exception e)
            {
                db.Ado.RollbackTran();
                return new ApiResult(e.Message, 500);
            }
            return new ApiResult();
        }

        public async Task<ApiResult> GetPagesAsync(KeyListQuery query)
        {
            var datas = await db.Queryable<Recycle, User>((r, u) => new JoinQueryInfos(JoinType.Inner, r.UserId == u.Id))
                    .WhereIF(!string.IsNullOrEmpty(query.Key), (r, u) => r.Remark.Contains(query.Key))
                  .OrderBy((r, u) => r.Id, OrderByType.Desc)
                  .Select((r, u) => new
                  {
                      UserName = u.Name,
                      r.CreateTime,
                      r.Id,
                      r.TableType,
                      r.Remark,
                      TenantName = SqlFunc.Subqueryable<Tenant>().Where(s => s.Id == r.TenantId).Select(s => s.Name),
                  }).ToPageAsync(query.Page, query.Limit);
            return new ApiResult(datas);
        }
    }
}